package com.lvt.design.pattern.create.single.demo03;

import java.util.concurrent.atomic.AtomicLong;

/**
 * desc：class
 * 双重检测
 *
 * @author LT
 * @date 2022/11/30
 */
public class IdGenerator {
    private AtomicLong id = new AtomicLong(0);
    /**
     * CPU 指令重排序可能导致在 IdGenerator 类的对象被关键字 new 创建并赋值给 instance 之后，
     * 还没来得及初始化（执行构造函数中的代码逻辑），就被另一个线程使用了。这样，另一个线程就使用了一个没有完整初始化的 IdGenerator 类的对象。
     * 要解决这个问题，我们只需要给 instance 成员变量添加 volatile 关键字来禁止指令重排序即可
     */
    private static volatile IdGenerator instance;

    private IdGenerator() {
    }

    public static IdGenerator getInstance() {
        if (instance == null) {
            synchronized (IdGenerator.class) {
                if (instance == null) {
                    return new IdGenerator();
                }
            }
        }
        return instance;
    }

    public Long getId() {
        return id.incrementAndGet();
    }
}
